home *** CD-ROM | disk | FTP | other *** search
- /* SCCS Id: @(#)winstat.c 3.1 92/3/7
- /* Copyright (c) Dean Luick, 1992 */
- /* NetHack may be freely redistributed. See license for details. */
-
- /*
- * Status window routines. This file supports both the "traditional"
- * tty status display and a "fancy" status display. A tty status is
- * made if a popup window is requested, otherewise a fancy status is
- * made. This code assumes that only one fancy status will ever be made.
- * Currently, only one status window (of any type) is _ever_ made.
- */
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <X11/Xaw/AsciiText.h>
- #include <X11/Xaw/Cardinals.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Label.h>
-
- #include "hack.h"
- #include "winX.h"
-
- extern const char *hu_stat[]; /* from eat.c */
- extern const char *enc_stat[]; /* from botl.c */
-
- static void update_fancy_status();
- static Widget create_fancy_status();
-
- void
- create_status_window(wp, create_popup, parent)
- struct xwindow *wp; /* window pointer */
- boolean create_popup;
- Widget parent;
- {
- XFontStruct *fs;
- Arg args[8];
- Cardinal num_args;
- Position top_margin, bottom_margin, left_margin, right_margin;
-
- wp->type = NHW_STATUS;
-
- if (!create_popup) {
- /*
- * If we are not creating a popup, then we must be the "main" status
- * window.
- */
- if (!parent)
- panic("create_status_window: no parent for fancy status");
- wp->status_information = 0;
- wp->w = create_fancy_status(parent, (Widget) 0);
- return;
- }
-
- wp->status_information =
- (struct status_info_t *) alloc(sizeof(struct status_info_t));
-
- init_text_buffer(&wp->status_information->text);
-
- num_args = 0;
- XtSetArg(args[num_args], XtNallowShellResize, False); num_args++;
- XtSetArg(args[num_args], XtNinput, False); num_args++;
-
- wp->popup = parent = XtCreatePopupShell("status_popup",
- topLevelShellWidgetClass,
- toplevel, args, num_args);
-
- num_args = 0;
- XtSetArg(args[num_args], XtNdisplayCaret, False); num_args++;
- XtSetArg(args[num_args], XtNscrollHorizontal,
- XawtextScrollWhenNeeded); num_args++;
- XtSetArg(args[num_args], XtNscrollVertical,
- XawtextScrollWhenNeeded); num_args++;
-
- wp->w = XtCreateManagedWidget(
- "status", /* name */
- asciiTextWidgetClass,
- parent, /* parent widget */
- args, /* set some values */
- num_args); /* number of values to set */
-
- /*
- * Adjust the height and width of the message window so that it
- * is two lines high and COLNO of the widest characters wide.
- */
-
- /* Get the font and margin information. */
- num_args = 0;
- XtSetArg(args[num_args], XtNfont, &fs); num_args++;
- XtSetArg(args[num_args], XtNtopMargin, &top_margin); num_args++;
- XtSetArg(args[num_args], XtNbottomMargin, &bottom_margin); num_args++;
- XtSetArg(args[num_args], XtNleftMargin, &left_margin); num_args++;
- XtSetArg(args[num_args], XtNrightMargin, &right_margin); num_args++;
- XtGetValues(wp->w, args, num_args);
-
- /* font height is ascent + descent */
- wp->pixel_height = 2 * (fs->ascent + fs->descent) +
- top_margin + bottom_margin;
- wp->pixel_width = COLNO * fs->max_bounds.width +
- left_margin + right_margin;
-
- /* Set the new width and height. */
- num_args = 0;
- XtSetArg(args[num_args], XtNwidth, wp->pixel_width); num_args++;
- XtSetArg(args[num_args], XtNheight, wp->pixel_height); num_args++;
- XtSetValues(wp->w, args, num_args);
- }
-
- void
- destroy_status_window(wp)
- struct xwindow *wp;
- {
- /* If status_information is defined, then it a "text" status window. */
- if (wp->status_information) {
- nh_XtPopdown(wp->popup);
- XtDestroyWidget(wp->popup);
- free((char *) wp->status_information);
- }
- wp->type = NHW_NONE;
- }
-
-
- /*
- * This assumes several things:
- * + Status has only 2 lines
- * + That both lines are updated in succession in line order.
- * + We didn't set stringInPlace on the widget.
- */
- void
- adjust_status(wp, str)
- struct xwindow *wp;
- const char *str;
- {
- Arg args[2];
- Cardinal num_args;
-
- if (!wp->status_information) {
- update_fancy_status(wp);
- return;
- }
-
- if (wp->cursy == 0) {
- clear_text_buffer(&wp->status_information->text);
- append_text_buffer(&wp->status_information->text, str, FALSE);
- return;
- }
- append_text_buffer(&wp->status_information->text, str, FALSE);
-
- /* Set new buffer as text. */
- num_args = 0;
- XtSetArg(args[num_args], XtNstring, wp->status_information->text.text);
- num_args++;
- XtSetValues(wp->w, args, num_args);
- }
-
-
- /* Fancy Status -------------------------------------------------------------*/
- static Widget init_info_form();
- static Widget init_column();
- static void set_widths();
- static void get_widths();
- static void create_widget();
- static const char *width_string();
- static void hilight_label();
- static void update_val();
-
- static int hilight_time = 1; /* number of turns to hilight a changed value */
-
- struct X_status_value {
- char *name; /* text name */
- int type; /* status type */
- Widget w; /* widget of name/value pair */
- int last_value; /* value displayed */
- int turn_count; /* last time the value changed */
- boolean set; /* if hilighed */
- boolean after_init; /* don't hilight on first change (init) */
- };
-
- /* valid type values */
- #define SV_VALUE 0 /* displays a label:value pair */
- #define SV_LABEL 1 /* displays a changable label */
- #define SV_NAME 2 /* displays an unchangeable name */
-
- /*
- * Form entry storage indices.
- */
- #define F_STR 0
- #define F_DEX 1
- #define F_CON 2
- #define F_INT 3
- #define F_WIS 4
- #define F_CHA 5
-
- #define F_NAME 6
- #define F_DLEVEL 7
- #define F_GOLD 8
- #define F_HP 9
- #define F_MAXHP 10
- #define F_POWER 11
- #define F_MAXPOWER 12
- #define F_AC 13
- #define F_LEVEL 14
- #define F_EXP 15
- #define F_ALIGN 16
- #define F_TIME 17
-
- #define F_HUNGER 18
- #define F_CONFUSED 19
- #define F_SICK 20
- #define F_BLIND 21
- #define F_STUNNED 22
- #define F_HALLU 23
- #define F_ENCUMBER 24
-
- #define NUM_STATS 25
-
- /*
- * Notes:
- * + Alignment needs a different init value, because -1 is an alignment.
- * + Blank value is 0 and should never change.
- */
- static struct X_status_value shown_stats[NUM_STATS] = {
- { "Strength", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /* 0*/
- { "Dexerity", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Constitution", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Intelligence", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Wisdom", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Charisma", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /* 5*/
-
- { "", SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* name */
- { "", SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* dlvl */
- { "Gold", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Hit Points", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Max HP", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /*10*/
- { "Power", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Max Power", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Armor Class", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Level", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Experience", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /*15*/
- { "Alignment", SV_VALUE, (Widget) 0, -2, 0, FALSE, FALSE },
- { "Time", SV_VALUE, (Widget) 0, -2, 0, FALSE, FALSE },
-
- { "", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /* hunger*/
- { "Confused", SV_NAME, (Widget) 0, 1, 0, FALSE, TRUE },
- { "Sick", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*20*/
- { "Blind", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
- { "Stunned", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
- { "Hallucinating", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
- { "", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*encumbr*/
-
- };
-
-
- /*
- * Set all widget values to a null string. This is used after all spacings
- * have been calculated so that when the window is popped up we don't get all
- * kinds of funny values being displayed.
- */
- void
- null_out_status()
- {
- int i;
- struct X_status_value *sv;
- Arg args[1];
-
- for (i = 0, sv = shown_stats; i < NUM_STATS; i++, sv++) {
- switch (sv->type) {
- case SV_VALUE:
- set_value(sv->w, "");
- break;
-
- case SV_LABEL:
- case SV_NAME:
- XtSetArg(args[0], XtNlabel, "");
- XtSetValues(sv->w, args, ONE);
- break;
-
- default:
- impossible("null_out_status: unknown type %d\n", sv->type);
- break;
- }
- }
- }
-
- /* This is almost an exact duplicate of hilight_value() */
- static void
- hilight_label(w)
- Widget w; /* label widget */
- {
- Arg args[2];
- Pixel fg, bg;
-
- XtSetArg(args[0], XtNforeground, &fg);
- XtSetArg(args[1], XtNbackground, &bg);
- XtGetValues(w, args, TWO);
-
- XtSetArg(args[0], XtNforeground, bg);
- XtSetArg(args[1], XtNbackground, fg);
- XtSetValues(w, args, TWO);
- }
-
-
- static void
- update_val(attr_rec, new_value)
- struct X_status_value *attr_rec;
- long new_value;
- {
- char buf[BUFSZ];
- Arg args[4];
-
- if (attr_rec->type == SV_LABEL) {
-
- if (attr_rec == &shown_stats[F_NAME]) {
-
- Strcpy(buf, plname);
- if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a';
- Strcat(buf, " the ");
- #ifdef POLYSELF
- if (u.mtimedone) {
- char mname[BUFSZ];
- int k = 0;
-
- Strcpy(mname, mons[u.umonnum].mname);
- while(mname[k] != 0) {
- if ((k == 0 || (k > 0 && mname[k-1] == ' ')) &&
- 'a' <= mname[k] && mname[k] <= 'z')
- mname[k] += 'A' - 'a';
- k++;
- }
- Strcat(buf, mname);
- } else
- #endif
- Strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female));
-
- } else if (attr_rec == &shown_stats[F_DLEVEL]) {
- if (In_endgame(&u.uz)) {
- Strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game"));
- } else {
- Strcpy(buf, dungeons[u.uz.dnum].dname);
- Sprintf(eos(buf), ", level %d", depth(&u.uz));
- }
- } else {
- impossible("update_val: unknown label type \"%s\"",
- attr_rec->name);
- return;
- }
-
- if (strcmp(buf, attr_rec->name) == 0) return; /* same */
-
- /* Set the label. */
- Strcpy(attr_rec->name, buf);
- XtSetArg(args[0], XtNlabel, buf);
- XtSetValues(attr_rec->w, args, ONE);
-
- } else if (attr_rec->type == SV_NAME) {
-
- if (attr_rec->last_value == new_value) return; /* no change */
-
- attr_rec->last_value = new_value;
-
- /* special cases: hunger and encumbrance */
- if (attr_rec == &shown_stats[F_HUNGER]) {
- XtSetArg(args[0], XtNlabel, hu_stat[new_value]);
- } else if (attr_rec == &shown_stats[F_ENCUMBER]) {
- XtSetArg(args[0], XtNlabel, enc_stat[new_value]);
- } else if (new_value) {
- XtSetArg(args[0], XtNlabel, attr_rec->name);
- } else {
- XtSetArg(args[0], XtNlabel, "");
- }
- XtSetValues(attr_rec->w, args, ONE);
-
- } else { /* a value pair */
- boolean force_update = FALSE;
-
- /* special case: time can be enabled & disabled */
- if (attr_rec == &shown_stats[F_TIME]) {
- static boolean flagtime = TRUE;
-
- if(flags.time && !flagtime) {
- set_name(attr_rec->w, shown_stats[F_TIME].name);
- force_update = TRUE;
- flagtime = flags.time;
- } else if(!flags.time && flagtime) {
- set_name(attr_rec->w, "");
- set_value(attr_rec->w, "");
- flagtime = flags.time;
- }
- if(!flagtime) return;
- }
- #ifdef POLYSELF
- /* special case: when polymorphed, show "HD", disable exp */
- else if (attr_rec == &shown_stats[F_LEVEL]) {
- static boolean lev_was_poly = FALSE;
-
- if (u.mtimedone && !lev_was_poly) {
- force_update = TRUE;
- set_name(attr_rec->w, "HD");
- lev_was_poly = TRUE;
- } else if (!u.mtimedone && lev_was_poly) {
- force_update = TRUE;
- set_name(attr_rec->w, shown_stats[F_LEVEL].name);
- lev_was_poly = FALSE;
- }
- } else if (attr_rec == &shown_stats[F_EXP]) {
- static boolean exp_was_poly = FALSE;
-
- if (u.mtimedone && !exp_was_poly) {
- force_update = TRUE;
- set_name(attr_rec->w, "");
- set_value(attr_rec->w, "");
- exp_was_poly = TRUE;
- } else if (!u.mtimedone && exp_was_poly) {
- force_update = TRUE;
- set_name(attr_rec->w, shown_stats[F_EXP].name);
- exp_was_poly = FALSE;
- }
- if (u.mtimedone) return; /* no display for exp when poly */
- }
- #endif
-
- if (attr_rec->last_value == new_value && !force_update) /* same */
- return;
-
- attr_rec->last_value = new_value;
-
- /* Special cases: strength, alignment and "clear". */
- if (attr_rec == &shown_stats[F_STR]) {
- if(new_value > 18) {
- if (new_value > 118)
- Sprintf(buf,"%d", new_value-100);
- else if(new_value < 118)
- Sprintf(buf, "18/%02d", new_value-18);
- else
- Strcpy(buf, "18/**");
- } else {
- Sprintf(buf, "%d", new_value);
- }
- } else if (attr_rec == &shown_stats[F_ALIGN]) {
-
- Strcpy(buf, (new_value == A_CHAOTIC) ? "Chaotic" :
- (new_value == A_NEUTRAL) ? "Neutral" :
- "Lawful" );
- } else {
- Sprintf(buf, "%d", new_value);
- }
- set_value(attr_rec->w, buf);
- }
-
- /*
- * Now hilight the changed information. Names, time and score don't
- * hilight. If first time, don't hilight. If already lit, don't do
- * it again.
- */
- if (attr_rec->type != SV_NAME && attr_rec != &shown_stats[F_TIME]) {
- if (attr_rec->after_init) {
- if(!attr_rec->set) {
- if (attr_rec->type == SV_LABEL)
- hilight_label(attr_rec->w);
- else
- hilight_value(attr_rec->w);
- attr_rec->set = TRUE;
- }
- attr_rec->turn_count = 0;
- } else {
- attr_rec->after_init = TRUE;
- }
- }
- }
-
- /*
- * Update the displayed status. The current code in botl.c updates
- * two lines of information. Both lines are always updated one after
- * the other. So only do our update when we update the second line.
- *
- * Information on the first line:
- * name, attributes, alignment, score
- *
- * Not done: score
- *
- * Information on the second line:
- * dlvl, gold, hp, power, ac, {level & exp or HD **}
- * status (hunger, conf, halu, stun, sick, blind), time, encumbrance
- *
- * [**] HD is shown instead of level and exp if POLYSELF is defined and
- * mtimedone is non-zero.
- */
- static void
- update_fancy_status(wp)
- struct xwindow *wp;
- {
- const struct X_status_value *sv;
- long val;
- int i;
-
- if (wp->cursy != 0) return; /* do a complete update when line 0 is done */
-
- #ifdef GCC_WARN
- val = 0;
- #endif
-
- for (i = 0, sv = shown_stats; i < NUM_STATS; i++, sv++) {
- switch (i) {
- case F_STR: val = (long) ACURR(A_STR); break;
- case F_DEX: val = (long) ACURR(A_DEX); break;
- case F_CON: val = (long) ACURR(A_CON); break;
- case F_INT: val = (long) ACURR(A_INT); break;
- case F_WIS: val = (long) ACURR(A_WIS); break;
- case F_CHA: val = (long) ACURR(A_CHA); break;
- /*
- * Label stats. With the exceptions of hunger and encumbrance,
- * these are either on or off. Pleae leave the ternary operators
- * the way they are. I want to specify 0 or 1, not a boolean.
- */
- case F_HUNGER: val = (long) u.uhs; break;
- case F_CONFUSED: val = (long) Confusion ? 1L : 0L; break;
- case F_SICK: val = (long) Sick ? 1L : 0L; break;
- case F_BLIND: val = (long) Blind ? 1L : 0L; break;
- case F_STUNNED: val = (long) Stunned ? 1L : 0L; break;
- case F_HALLU: val = (long) Hallucination ? 1L : 0L; break;
- case F_ENCUMBER: val = (long) near_capacity(); break;
-
- case F_NAME: val = (long) 0L; break; /* special */
- case F_DLEVEL: val = (long) 0L; break; /* special */
- case F_GOLD: val = (long) u.ugold; break;
- #ifdef POLYSELF
- case F_HP: val = (long) (u.mtimedone ?
- (u.mh > 0 ? u.mh : 0):
- (u.uhp > 0 ? u.uhp : 0)); break;
- case F_MAXHP: val = (long) (u.mtimedone ? u.mhmax :
- u.uhpmax); break;
- #else
- case F_HP: val = (long) (u.uhp > 0 ? u.uhp : 0); break;
- case F_MAXHP: val = (long) u.uhpmax; break;
- #endif
- case F_POWER: val = (long) u.uen; break;
- case F_MAXPOWER: val = (long) u.uenmax; break;
- case F_AC: val = (long) u.uac; break;
- #ifdef POLYSELF
- case F_LEVEL: val = (long) (u.mtimedone ?
- mons[u.umonnum].mlevel :
- u.ulevel); break;
- #else
- case F_LEVEL: val = (long) u.ulevel; break;
- #endif
- case F_EXP: val = (long) u.uexp; break;
- case F_ALIGN: val = (long) u.ualign.type; break;
- case F_TIME: val = flags.time ? (long) moves : 0L; break;
- default:
- {
- /*
- * There is a possible infinite loop that occurs with:
- *
- * impossible->pline->flush_screen->bot->bot{1,2}->
- * putstr->adjust_status->update_other->impossible
- *
- * Break out with this.
- */
- static boolean active = FALSE;
- if (!active) {
- active = TRUE;
- impossible("update_other: unknown shown value");
- active = FALSE;
- }
- break;
- }
- }
- update_val(sv, val);
- }
- }
-
- /*
- * Turn off hilighted status values after a certain amount of turns.
- */
- void
- check_turn_events()
- {
- int i;
- struct X_status_value *sv;
-
- for (sv = shown_stats, i = 0; i < NUM_STATS; i++, sv++) {
- if (!sv->set) continue;
-
- if (sv->turn_count++ >= hilight_time) {
- if (sv->type == SV_LABEL)
- hilight_label(sv->w);
- else
- hilight_value(sv->w);
- sv->set = FALSE;
- }
- }
- }
-
- /* Initialize alternate status ============================================= */
-
- /* Return a string for the initial width. */
- static const char *
- width_string(sv_index)
- int sv_index;
- {
- switch (sv_index) {
- case F_STR: return "018/**";
- case F_DEX:
- case F_CON:
- case F_INT:
- case F_WIS:
- case F_CHA: return "088"; /* all but str never get bigger */
-
- case F_HUNGER: return shown_stats[F_HUNGER].name;
- case F_CONFUSED:return shown_stats[F_CONFUSED].name;
- case F_SICK: return shown_stats[F_SICK].name;
- case F_BLIND: return shown_stats[F_BLIND].name;
- case F_STUNNED: return shown_stats[F_STUNNED].name;
- case F_HALLU: return shown_stats[F_HALLU].name;
- case F_ENCUMBER:return shown_stats[F_ENCUMBER].name;
-
- case F_NAME:
- case F_DLEVEL: return "";
- case F_HP:
- case F_MAXHP: return "9999";
- case F_POWER:
- case F_MAXPOWER:return "999";
- case F_AC: return "-99";
- case F_LEVEL: return "99";
- case F_GOLD:
- case F_EXP: return "4294967295"; /* max ulong */
- case F_ALIGN: return "Neutral";
- case F_TIME: return "4294967295"; /* max ulong */
- }
- impossible("width_string: unknown index %d\n", sv_index);
- return "";
- }
-
- static void
- create_widget(parent, sv, sv_index)
- Widget parent;
- struct X_status_value *sv;
- int sv_index;
- {
- Arg args[4];
- Cardinal num_args;
-
- switch (sv->type) {
- case SV_VALUE:
- sv->w = create_value(parent, sv->name);
- set_value(sv->w, width_string(sv_index));
- break;
- case SV_LABEL:
- /* Labels get their own buffer. */
- sv->name = (char *) alloc(BUFSZ);
- sv->name[0] = '\0';
-
- num_args = 0;
- XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
- XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++;
- sv->w = XtCreateManagedWidget(
- sv_index == F_NAME ? "name" : "dlevel",
- labelWidgetClass,
- parent,
- args, num_args);
- break;
- case SV_NAME:
- num_args = 0;
- XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
- XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++;
- sv->w = XtCreateManagedWidget(sv->name,
- labelWidgetClass,
- parent,
- args, num_args);
- break;
- default:
- panic("create_widget: unknown type %d", sv->type);
- }
- }
-
- /*
- * Get current width of value. width2p is only valid for SV_LABEL types.
- */
- static void
- get_widths(sv, width1p, width2p)
- struct X_status_value *sv;
- int *width1p, *width2p;
- {
- Arg args[1];
- Dimension width;
-
- switch (sv->type) {
- case SV_VALUE:
- *width1p = get_name_width(sv->w);
- *width2p = get_value_width(sv->w);
- break;
- case SV_LABEL:
- case SV_NAME:
- XtSetArg(args[0], XtNwidth, &width);
- XtGetValues(sv->w, args, ONE);
- *width1p = width;
- *width2p = 0;
- break;
- default:
- panic("get_widths: unknown type %d", sv->type);
- }
- }
-
- static void
- set_widths(sv, width1, width2)
- struct X_status_value *sv;
- int width1, width2;
- {
- Arg args[1];
-
- switch (sv->type) {
- case SV_VALUE:
- set_name_width(sv->w, width1);
- set_value_width(sv->w, width2);
- break;
- case SV_LABEL:
- case SV_NAME:
- XtSetArg(args[0], XtNwidth, (width1+width2));
- XtSetValues(sv->w, args, ONE);
- break;
- default:
- panic("set_widths: unknown type %d", sv->type);
- }
- }
-
- static Widget
- init_column(name, parent, top, left, col_indices)
- char *name;
- Widget parent, top, left;
- int *col_indices;
- {
- Widget form;
- Arg args[4];
- Cardinal num_args;
- int max_width1, width1, max_width2, width2;
- int *ip;
- struct X_status_value *sv;
-
- num_args = 0;
- if (top != (Widget) 0) {
- XtSetArg(args[num_args], XtNfromVert, top); num_args++;
- }
- if (left != (Widget) 0) {
- XtSetArg(args[num_args], XtNfromHoriz, left); num_args++;
- }
- XtSetArg(args[num_args], XtNdefaultDistance, 0); num_args++;
- form = XtCreateManagedWidget(name,
- formWidgetClass,
- parent, args, num_args);
-
- max_width1 = max_width2 = 0;
- for (ip = col_indices; *ip >= 0; ip++) {
- sv = &shown_stats[*ip];
- create_widget(form, sv, *ip); /* will set init width */
- if (ip != col_indices) { /* not first */
- num_args = 0;
- XtSetArg(args[num_args], XtNfromVert, shown_stats[*(ip-1)].w);
- num_args++;
- XtSetValues(sv->w, args, num_args);
- }
- get_widths(sv, &width1, &width2);
- if (width1 > max_width1) max_width1 = width1;
- if (width2 > max_width2) max_width2 = width2;
- }
- for (ip = col_indices; *ip >= 0 ; ip++) {
- set_widths(&shown_stats[*ip], max_width1, max_width2);
- }
-
- /* There is room behind the end marker for the two widths. */
- *++ip = max_width1;
- *++ip = max_width2;
-
- return form;
- }
-
- /*
- * These are the orders of the displayed columns. Change to suit. The -1
- * indicates the end of the column. The two numbers after that are used
- * to store widths that are calculated at run-time.
- */
- static int attrib_indices[] = { F_STR,F_DEX,F_CON,F_INT,F_WIS,F_CHA, -1,0,0 };
- static int status_indices[] = { F_HUNGER, F_CONFUSED, F_SICK, F_BLIND,
- F_STUNNED, F_HALLU, F_ENCUMBER, -1,0,0 };
-
- static int col2_indices[] = { F_MAXHP,F_ALIGN,F_TIME,F_EXP,F_MAXPOWER,-1,0,0 };
- static int col1_indices[] = { F_HP, F_AC, F_GOLD, F_LEVEL, F_POWER, -1,0,0 };
-
-
- /*
- * Produce a form that looks like the following:
- *
- * name
- * dlevel
- * col1_indices[0] col2_indices[0]
- * col1_indices[1] col2_indices[1]
- * . .
- * . .
- * col1_indices[n] col2_indices[n]
- */
- static Widget
- init_info_form(parent, top, left)
- Widget parent, top, left;
- {
- Widget form, col1;
- struct X_status_value *sv_name, *sv_dlevel;
- Arg args[6];
- Cardinal num_args;
- int total_width, *ip;
-
- num_args = 0;
- if (top != (Widget) 0) {
- XtSetArg(args[num_args], XtNfromVert, top); num_args++;
- }
- if (left != (Widget) 0) {
- XtSetArg(args[num_args], XtNfromHoriz, left); num_args++;
- }
- XtSetArg(args[num_args], XtNdefaultDistance, 0); num_args++;
- form = XtCreateManagedWidget("status_info",
- formWidgetClass,
- parent,
- args, num_args);
-
- /* top of form */
- sv_name = &shown_stats[F_NAME];
- create_widget(form, sv_name, F_NAME);
-
- /* second */
- sv_dlevel = &shown_stats[F_DLEVEL];
- create_widget(form, sv_dlevel, F_DLEVEL);
-
- num_args = 0;
- XtSetArg(args[num_args], XtNfromVert, sv_name->w); num_args++;
- XtSetValues(sv_dlevel->w, args, num_args);
-
- /* two columns beneath */
- col1 = init_column("name_col1", form, sv_dlevel->w,
- (Widget) 0, col1_indices);
- (void) init_column("name_col2", form, sv_dlevel->w,
- col1, col2_indices);
-
- /* Add calculated widths. */
- for (ip = col1_indices; *ip >= 0; ip++)
- ; /* skip to end */
- total_width = *++ip;
- total_width += *++ip;
- for (ip = col2_indices; *ip >= 0; ip++)
- ; /* skip to end */
- total_width += *++ip;
- total_width += *++ip;
-
- XtSetArg(args[0], XtNwidth, total_width);
- XtSetValues(sv_name->w, args, ONE);
- XtSetArg(args[0], XtNwidth, total_width);
- XtSetValues(sv_dlevel->w, args, ONE);
-
- return form;
- }
-
- /*
- * Create the layout for the fancy status. Return a form widget that
- * contains everything.
- */
- static Widget
- create_fancy_status(parent, top)
- Widget parent, top;
- {
- Widget form; /* The form that surrounds everything. */
- Widget w;
- Arg args[6];
- Cardinal num_args;
-
- num_args = 0;
- if (top != (Widget) 0) {
- XtSetArg(args[num_args], XtNfromVert, top); num_args++;
- }
- XtSetArg(args[num_args], XtNdefaultDistance, 0); num_args++;
- XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
- form = XtCreateManagedWidget("fancy_status",
- formWidgetClass,
- parent,
- args, num_args);
-
- w = init_info_form(form, (Widget) 0, (Widget) 0);
- w = init_column("status_attributes",form, (Widget) 0, w, attrib_indices);
- (void) init_column("status_condition", form, (Widget) 0, w, status_indices);
- return form;
- }
-
-